package com.ygqh.customs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ygqh.common.okhttp.DefaultOkHttp3Client;
import com.ygqh.common.okhttp.exception.OkHttp3Exception;
import com.ygqh.common.utils.StringUtil;
import com.ygqh.customs.config.CustomsConfig;
import com.ygqh.customs.domain.PayExInfo;
import com.ygqh.customs.domain.PayExchangeInfoHead;
import com.ygqh.customs.domain.PayExchangeInfoList;
import com.ygqh.customs.handler.DataUpParamHandler;
import com.ygqh.customs.mapper.YgCustomsDataUpMapper;
import com.ygqh.customs.model.DataUpListModel;
import com.ygqh.customs.model.ResultSet;
import com.ygqh.customs.po.YgCustomsDataUp;
import com.ygqh.customs.request.DataUpRequest;
import com.ygqh.customs.request.DataUpSearchRequest;
import com.ygqh.customs.request.PlatDataOpenRequest;
import com.ygqh.customs.response.PlatDataResponse;
import com.ygqh.customs.service.YgCustomsDataUpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 〈〉
 *
 * @author guohao
 * @date 2019/3/15 12:18
 * @since 1.0.0
 */
@Slf4j
@Service
public class YgCustomsDataUpServiceImpl implements YgCustomsDataUpService {

    @Autowired
    private YgCustomsDataUpMapper ygCustomsDataUpMapper;
    @Autowired
    private DataUpParamHandler dataUpParamHandler;
    @Autowired
    private CustomsConfig customsConfig;

    private boolean checkParam(Map<String, String> paramMap) {
        return paramMap != null && !StringUtil.isBlank(paramMap.get("openReq"));
    }

    @Override
    public PlatDataResponse platDataOpen(Map<String, String> map) {
        PlatDataResponse response = new PlatDataResponse();
        if (!checkParam(map)) {
            response.setCode("20000");
            response.setMessage("request missing openReq");
            return response;
        }
        PlatDataOpenRequest openReq = JSON.parseObject(map.get("openReq"), new TypeReference<PlatDataOpenRequest>() {
        });
        response = this.platDataOpen(openReq);
        return response;
    }


    /**
     * 保存企业接收海关发起的支付相关实时数据获取请求
     *
     * @param request 海关请求信息
     * @return int
     */
    private PayExInfo savePlatDataOpen(PlatDataOpenRequest request) {
        PayExInfo dataUpSignParam = dataUpParamHandler.build(request);
        YgCustomsDataUp customsDataUp = new YgCustomsDataUp();
        customsDataUp.setSessionId(request.getSessionID());
        customsDataUp.setOrderNo(request.getOrderNo());
        customsDataUp.setPayExchangeInfoHead(dataUpSignParam.toPayExchangeInfoHeadJSONString());
        customsDataUp.setPayExchangeInfoList(dataUpSignParam.toPayExchangeInfoListsJSONString());
        customsDataUp.setDataOpenTime(new Date(request.getServiceTime()));
        customsDataUp.setCreateTime(new Date());
        customsDataUp.setCertNo(dataUpSignParam.getCertNo());
        ygCustomsDataUpMapper.insertSelective(customsDataUp);

        dataUpSignParam.setDataUpId(customsDataUp.getId());
        return dataUpSignParam;
    }

    @Override
    public void sendDataToSign(PayExInfo dataUpSignParam) throws OkHttp3Exception {
        dataUpSignParam.setServiceTime(System.currentTimeMillis());
        DefaultOkHttp3Client.httpPost(customsConfig.getLocalSignUrl(), dataUpSignParam.toJSONString(), DefaultOkHttp3Client.JSON_MEDIA_TYPE);
    }

    @Override
    public PlatDataResponse platDataUp(DataUpRequest dataUpRequest) {
        log.info("platDataUp request: {}", dataUpRequest);
        PlatDataResponse platDataResponse;
        try {
            YgCustomsDataUp customsDataUp = ygCustomsDataUpMapper.selectBySessionId(dataUpRequest.getSessionID());
            PayExInfo payExInfo = new PayExInfo();
            payExInfo.setSessionID(customsDataUp.getSessionId());
            payExInfo.setCertNo(customsDataUp.getCertNo());
            payExInfo.setSignValue(dataUpRequest.getSignValue());
            payExInfo.setPayExchangeInfoHead(JSON.parseObject(customsDataUp.getPayExchangeInfoHead(), new TypeReference<PayExchangeInfoHead>() {
            }));
            payExInfo.setPayExchangeInfoLists(JSON.parseObject(customsDataUp.getPayExchangeInfoList(), new TypeReference<ArrayList<PayExchangeInfoList>>() {
            }));
            payExInfo.setServiceTime(dataUpRequest.getServiceTime());
            Map<String, String> param = new HashMap<>();
            String payExInfoStr = payExInfo.toJSONString();
            param.put("payExInfoStr", payExInfoStr);
            log.info("platDataUp -> payExInfoStr : {}", payExInfoStr);
            platDataResponse = DefaultOkHttp3Client.httpFormPost(customsConfig.getCustomsDataUpUrl(),
                    param, new TypeReference<PlatDataResponse>() {
                    });

            log.info("platDataUp response: {}", platDataResponse);

            if (platDataResponse.ok()) {
                writeBackUpStatus(dataUpRequest);
            } else {
                log.warn("platDataUp fail -> dataUpRequest : {} ,platDataResponse : {}", dataUpRequest, platDataResponse);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("platDataUp fail: {}", e);
            platDataResponse = new PlatDataResponse();
            platDataResponse.setCode("400");
            platDataResponse.setMessage(e.getMessage());
        }
        return platDataResponse;
    }

    @Override
    public ResultSet<DataUpListModel> search(DataUpSearchRequest searchRequest) {
        int count = ygCustomsDataUpMapper.count(searchRequest);
        List<DataUpListModel> dataUpListModels;
        if (count > 0) {
            dataUpListModels = ygCustomsDataUpMapper.selectList(searchRequest);
        } else {
            dataUpListModels = Collections.emptyList();
        }
        return new ResultSet<>(count, dataUpListModels);
    }

    private void writeBackUpStatus(DataUpRequest dataUpRequest) {

        YgCustomsDataUp customsDataUp = new YgCustomsDataUp();
        customsDataUp.setId(dataUpRequest.getDataUpId());
        customsDataUp.setUpServiceTime(new Date(dataUpRequest.getServiceTime()));
        customsDataUp.setSignValue(dataUpRequest.getSignValue());
        customsDataUp.setUpStatus(1);
        ygCustomsDataUpMapper.updateByPrimaryKeySelective(customsDataUp);
    }


    @Override
    public PlatDataResponse platDataOpen(PlatDataOpenRequest request) {
        try {
            PayExInfo dataUpSignParam = savePlatDataOpen(request);
            sendDataToSign(dataUpSignParam);
        } catch (Exception e) {
            log.error("platDataOpen fail: sessionID: {},errorMsg: {}", request.getSessionID(), e);
        }

        PlatDataResponse response = new PlatDataResponse();
        response.setCode("10000");
        response.setMessage("");
        response.setServiceTime(System.currentTimeMillis());

        return response;
    }

    @Override
    public void sendDataToSign(PlatDataOpenRequest request) {
        try {
            YgCustomsDataUp customsDataUp = ygCustomsDataUpMapper.selectBySessionId(request.getSessionID());
            PayExInfo dataUpSignParam = new PayExInfo();
            dataUpSignParam.setServiceTime(System.currentTimeMillis());
            dataUpSignParam.setDataUpId(customsDataUp.getId());
            dataUpSignParam.setSessionID(customsDataUp.getSessionId());
            dataUpSignParam.setCertNo(customsDataUp.getCertNo());
            dataUpSignParam.setPayExchangeInfoHead(JSON.parseObject(customsDataUp.getPayExchangeInfoHead(), new TypeReference<PayExchangeInfoHead>() {
            }));
            dataUpSignParam.setPayExchangeInfoLists(JSON.parseObject(customsDataUp.getPayExchangeInfoList(), new TypeReference<ArrayList<PayExchangeInfoList>>() {
            }));
            sendDataToSign(dataUpSignParam);
        } catch (OkHttp3Exception e) {
            e.printStackTrace();
            log.error("platDataOpen fail: sessionID: {},errorMsg: {}", request.getSessionID(), e);
        }
    }
}
